﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using vudu.ClasesDominio;
using vudu.Logica.Fachada;
using vudu.Presentacion.Contrato.VU_03_Gestionar_Pensum_por_Escuela;

namespace vudu.Presentacion.Presentador.VU_03_Gestionar_Pensum_por_Escuela
{
    public class PresentadorCrearPensumEtapaII
    {
        #region Atributos privados
        
        private EnlaceLogico _fachada;
        private IContratoCrearPensumEtapaII _vista;
        private Pensum _pensumActual;
        private List<Materia> _materiasAEscoger;
        private Escuela _usuarioEscuela;
        private bool _etapaII;
        private string _rol;

        #endregion

        #region Constructor

        public PresentadorCrearPensumEtapaII(IContratoCrearPensumEtapaII vista, EnlaceLogico fachada)
        {
            _vista = vista;
            _fachada = (EnlaceLogico)_vista.Sesion["Fachada"];
            if (_fachada != null)
                _usuarioEscuela = (Escuela)_fachada.RolActual;
            _rol = (string)_vista.Sesion["TipoRol"];
            _etapaII = true;
            _pensumActual = new Pensum();
            _materiasAEscoger = new List<Materia>();

            _materiasAEscoger= _vista.Sesion["MateriasParaPensum"] as List<Materia>;
            _pensumActual = _vista.Sesion["PensumAConsultar"] as Pensum;
        }

        #endregion

        #region Propiedades


        public string Rol
        {
            get { return _rol; }
            set { _rol = value; }
        }

        public Pensum PensumActual
        {
            get { return _pensumActual; }
            set { _pensumActual = value; }
        }

        public List<Materia> MateriasAEscoger
        {
            get { return _materiasAEscoger; }
            set { _materiasAEscoger = value; }
        }

        public bool EtapaII
        {
            get { return _etapaII; }
            set { _etapaII = value; }
        }

        #endregion
        
        #region Metodos

        /// <summary>
        /// metodo que se encarga de escribir el nombre del usuario logeado
        /// </summary>
        public void MostrarNombreUsuario()
        {
            Escuela esc = (Escuela)_fachada.RolActual;
            _vista.Actor.Text = _rolUsuario + _separador + esc.NombreEscuela;
        }

        /// <summary>
        /// Metodo que se encagara de crear los semestres del pensum en funcion a la seleccion del usuario
        /// </summary>
        /// <param name="pensumActual">
        /// objeto pensum el cual voy a insertar semestralmenta las materias
        /// </param>
        public void CargarMateriasSemestralesDe(Pensum pensumActual)
        {
            try
            {
                if (pensumActual != null)
                {
                    List<Prelacion> semestreActual = new List<Prelacion>();
                    int numeroSemestre = ObtenerNumeroDeSemestre();
                    semestreActual = ObtenerMateriasDeSemestre(numeroSemestre);
                    if (semestreActual.Count > 0)
                    {
                        bool resp = InsertarSemestre(semestreActual);
                        if (resp)
                        {
                            OcurreExito(_mensajeExito1);//las materias se han cargado exitosamente
                        }
                        else
                        {
                            OcurreError(_mensajeError4);//ha ocurrido un error al asignar el semestre
                        }
                    }
                    else
                    {
                        OcurreError(_mensajeError4);//error al agregar a semestre
                    }
                    //metodo que recorre la tabla
                }
            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }
        }

        
        /// <summary>
        /// metodo que se encarga de obteenr el numero de semestre escogido
        /// </summary>
        /// <returns>numero de semestre</returns>
        private int ObtenerNumeroDeSemestre()
        {
            int numSemestre = 0;

            try
            {
                numSemestre = int.Parse(_vista.Lista.SelectedValue);
                numSemestre = numSemestre + 1;

            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }
            return numSemestre;
        }

        /// <summary>
        /// Metodo que se encarga de obtener y encapsultar la amteria del gridview de materias
        /// junto al numero de semestre que le estoy pasando
        /// </summary>
        /// <param name="row">fila donde se encuentra la materia escogida</param>
        /// <param name="numSemestre">semestre al cual pertenecera</param>
        /// <returns>objeto materia encapsulado con su semestre</returns>
        private Prelacion ObtenerMateriaDeFila(GridViewRow row, int numSemestre)
        {
            Prelacion materiaSemestre = new Prelacion();
            Materia mat = new Materia();
            string nombreMat = row.Cells[1].Text;
            string codMat = row.Cells[2].Text;
            string uc = row.Cells[3].Text;
            try
            {
                if (!uc.Contains('-') && !codMat.Contains('-'))
                {
                    mat.Nombre = nombreMat;
                    mat.Codigo = int.Parse(codMat);
                    mat.NumeroCreditos = int.Parse(uc);
                    materiaSemestre.MiMateriaPensum = mat;
                    materiaSemestre.SemestreMateriaPensum = numSemestre;
                }
            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }
            return materiaSemestre;
        }

        /// <summary>
        /// metodo que se encarga de extraer lasmaterias seleccionadas del gridview y 
        /// retorna la lista de materia por un semestre
        /// </summary>
        /// <param name="numSemestre">retorno la lista de materias del semestre q le asigne</param>
        /// <returns>Lista de materias de semestre</returns>
        private List<Prelacion> ObtenerMateriasDeSemestre(int numSemestre)
        {
            List<Prelacion> semestre = new List <Prelacion>();
                
            foreach (GridViewRow row in _vista.TablaMaterias.Rows)
            {
                CheckBox check = row.FindControl("chkSeleccionEscoger") as CheckBox;
                if (check.Checked)
                {
                    Prelacion materiaSemestre = new Prelacion();
                    //obtengo el objeto prelacion encapsulando la materia y su numero de semestre
                    materiaSemestre = ObtenerMateriaDeFila(row, numSemestre);
                    //elimino esa materia de mi lista auxiliar
                    _materiasAEscoger.Remove(materiaSemestre.MiMateriaPensum);
                    //agrego a la lista del semestre actual
                    semestre.Add(materiaSemestre);
                    //agrego ala lista de materias de todo el pensum
                }
            }

            return semestre;
        }

        /// <summary>
        /// Metodo que se encarga de insertar en la base de datos cada objeto prelacion 
        /// para formar la base de datos
        /// </summary>
        /// <param name="semestreActual"></param>
        /// <returns>true si se inserto
        /// false si no se inserto</returns>
        private bool InsertarSemestre(List<Prelacion> semestreActual)
        {
            bool resp = false;
            //llamo al comando
            List<Prelacion> semestre = semestreActual;
            if((semestre!=null) && (_pensumActual!=null) )
            {
                resp = _fachada.InsertarMateriaSemestre(_pensumActual,semestre);
            }
            return resp;
        }

        /// <summary>
        /// metodo que se encarga de calcular la diferencia entre el numero de materias traidas y el numero de filas total(8)
        /// para ayudar a rellenar las filas vacias del gridview de materia
        /// </summary>
        /// <param name="totalFilas"></param>
        /// <returns></returns>
        private int Diferencia(int totalFilas)
        {
            int diferencia = 0;
            if (totalFilas < _vista.TablaMateriasPensum.PageSize)
            {
                diferencia = _vista.TablaMateriasPensum.PageSize - totalFilas;
            }
            return diferencia;
        }

        /// <summary>
        /// Cargael Gridview con las materias dependiendo de la informacionque se encuentre en la 
        /// lista "_lsita" la cual contiene la lista de materias pertenecientes a la escuela
        /// seleccionada por el dropdwonlist
        /// </summary>
        public void CargarTablaMaterias(List<Materia> materias)
        {
            DataTable table = new DataTable();
            int diferencia = 0;
            table.Columns.Add("Nombre", typeof(string));
            table.Columns.Add("Codigo", typeof(string));
            table.Columns.Add("U.C.", typeof(string));
            try
            {
                if (materias != null)
                {
                    diferencia = Diferencia(materias.Count);
                    foreach (Materia materia in materias)
                    {
                        String nombreMateria = materia.Nombre;
                        if (nombreMateria != null)
                        {
                            table.Rows.Add(materia.Nombre, materia.Codigo, materia.NumeroCreditos);
                        }
                    }
                    for (int i = 0; i < diferencia; i++)
                    {
                        table.Rows.Add("-", "-", "-");
                    }
                    this._vista.TablaMaterias.DataSource = table;
                    this._vista.TablaMaterias.DataBind();
                }

            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }

        }

        /// <summary>
        /// Metodo que se encarga de obtener la materia encapsulada en el objeto prelacion
        /// de la lista de semestres(objeto prelacion encapsulala materia, 
        /// su numero de semestre y lista de materias)
        /// </summary>
        /// <param name="materiaSemestre">objeto prelacion encapsulado</param>
        /// <returns>objeto materia seleccionado
        /// </returns>
        private Materia ObtenerMateriaDePrelacion(Prelacion materiaSemestre)
        {
            Materia materia = new Materia();
            if (materiaSemestre != null)
            {
                materia = materiaSemestre.MiMateriaPensum;
            }
            return materia;
        }

        /// <summary>
        /// Carga el Gridview de las materias que tiene el pensum hasta los momentos en orden de semestre
        /// </summary>
        public void CargarTablaMateriasPensum()
        {
            List<Prelacion> materiasSemestre = new List<Prelacion>();
            DataTable table = new DataTable();
            int diferencia = 6;
            table.Columns.Add("Nombre", typeof(string));
            table.Columns.Add("Codigo", typeof(string));
            table.Columns.Add("U.C.", typeof(string));
            table.Columns.Add("Semestre", typeof(string));

            try
            {
                if (_pensumActual != null)
                {
                    materiasSemestre = _fachada.ConsultarMateriasDeUnPensum(_pensumActual.IdPensum);
                    diferencia = Diferencia(materiasSemestre.Count);
                    foreach (Prelacion materiaSemestre in materiasSemestre)
                    {
                        Materia materia = this.ObtenerMateriaDePrelacion(materiaSemestre);
                        
                        if (materia != null)
                        {
                            table.Rows.Add(materia.Nombre, materia.Codigo, materia.NumeroCreditos, materiaSemestre.SemestreMateriaPensum);
                        }
                    }
                    
                }
                for (int i = 0; i < diferencia; i++)
                {
                    table.Rows.Add("-", "-", "-", "-");
                }
                this._vista.TablaMateriasPensum.DataSource = table;
                this._vista.TablaMateriasPensum.DataBind();

            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }

            _vista.Sesion["MateriasParaPensum"] = _materiasAEscoger;
        }

        /// <summary>
        /// Metodo que se encarga de del control de la paginacion del gridview
        /// de materis a escoger para armar los semestres de pensum
        /// </summary>
        /// <param name="e">
        /// evento que controla la paginacion del gridview de materias a escoger</param>
        public void PaginacionMateriasAEscoger(GridViewPageEventArgs e)
        {
            _vista.TablaMaterias.PageIndex = e.NewPageIndex;
            this.CargarTablaMaterias(_materiasAEscoger);
        }

        /// <summary>
        /// Metodo que se encarga de del control de la paginacion del gridview
        /// de materis a escoger para armar los semestres de pensum
        /// </summary>
        /// <param name="e">
        /// evento que controla la paginacion del gridview de materias a escoger</param>
        public void PaginacionMateriasPensum(GridViewPageEventArgs e)
        {
            _vista.TablaMateriasPensum.PageIndex = e.NewPageIndex;
            this.CargarTablaMateriasPensum();
        }

        /// <summary>
        /// metodo que se encargara de decidir hacia que pagina redireccionar en funcion a la etapa actual
        /// </summary>
        /// <returns>nombre de pagina a redireccionar
        /// true: CrearPensumEtapaII.aspx
        /// false: CrearPensumEtapaIII.aspx
        /// </returns>
        public string RedireccionarA()
        {
            string paginaDestino = "";
            //algun metodo que se encargue deevaluar si la lista de materias a escoger se acabo

            if (_etapaII)
            {
                paginaDestino = _paginaActual;
            }
            else
            {
                paginaDestino = _paginaSiguiente;
            }
            return paginaDestino;
        }

        /// <summary>
        /// metodo que pregunta si ya esta todo listo para pasar a la siguiente etapa
        /// </summary>
        public void DefinirEtapa()
        {
            if (SeTerminaronLasMaterias())
            {
                _vista.Sesion["MateriasParaPensum"] = null;
                _vista.Sesion["numeroEtapa"] = 3;//actualizo el numero de la siguiente etapa
                _etapaII = false;
            }
            else 
            {
                OcurreError(_mensajeError3);//debe asignar todas las materias a un semestre
            }
           
        }
        private bool SeTerminaronLasMaterias()
        {
            bool resp = false;
            if (_materiasAEscoger != null)
            {
                if (_materiasAEscoger.Count == 0)
                    resp = true;
            }
            return resp;
        }

        /// <summary>
        /// Metodo que imprime un mensaje en la pagina al ocurrir un error
        /// </summary>
        /// <param name="info">
        /// mensaje de error
        /// </param>
        public void OcurreError(String info)
        {
            _vista.Error.Text = info;
            _vista.Error.ForeColor = System.Drawing.Color.Red;
            _vista.Error.Visible = true;
        }

        /// <summary>
        /// mensaje que imprime mensaje de exito
        /// </summary>
        /// <param name="info"></param>
        public void OcurreExito(string info)
        {
            _vista.Error.Text = info;
            _vista.Error.CssClass = _trassaccionExitosa;
            _vista.Error.ForeColor = System.Drawing.Color.Green;
            _vista.Error.Visible = true;
        }
        #endregion

        #region Constantes

        private const string _trassaccionExitosa = "transaccionExitosa";
        private const string _paginaActual = "CrearPensumEtapaII.aspx";
        private const string _paginaSiguiente = "CrearPensumEtapaIII.aspx";
        private const string _mensajeExito1 = "Operacion Exitosa: La(s) materia(s) se agregaron exitosamente";
        private const string _mensajeError1 = "Operacion Fallida: Disculpe, ya no quedan materias para escoger";
        private const string _mensajeError2 = "Operacion Fallida: Ha Ocurrido una Excepcion Inesperada";
        private const string _mensajeError3 = "Operacion Fallida: Debe Asignar todas las materias a un semestre";
        private const string _mensajeError4 = "Operacion Fallida: Ha ocurrido un error al asignar el semestre";
        private const string _rolUsuario = "Escuela";
        private const string _separador = ": ";

        #endregion


    }
}